#include <iostream>
#include <string>
#include "Socket.hpp"
#include "Protocol.hpp"
#include "InetAddr.hpp"
#include <memory>
#include <ctime>

using namespace protocol_ns;
using namespace socket_ns;

void Usage(std::string proc)
{
    std::cout << "Usage: " << proc << " serverip" << " serverport" << std::endl;
}

// tcpclinet serverip serverport
int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        Usage(argv[0]);
        return 1;
    }
    std::string serverip = argv[1];
    uint16_t serverport = std::stoi(argv[2]);
    // 构建目标主机
    InetAddr serveraddr(serverip, serverport);
    std::unique_ptr<TcpSocket> cli = std::make_unique<TcpSocket>();
    bool res = cli->BuileClientSocket(serveraddr);
    std::string inbuffer;
    Factory factory;
    while (res)
    {
        sleep(1);
        std::string str;
        // 由于服务端sleep(5)，每个1秒发，可能发不过去，对面没人读，默认不发了
        // for (int i = 0; i < 5; i++)
        // {
        //     // 1. 工厂产生Request
        //     auto req = factory.BuildRequest();
        //     // 2. 序列化
        //     std::string send_str;
        //     req->Serialize(&send_str);
        //     std::cout << "Serialize: \n"
        //               << send_str << std::endl;
        //     // 3. 进行添加报头
        //     send_str = EnCode(send_str);
        //     std::cout << "Encode: \n"
        //               << send_str << std::endl;
        //     str += send_str;
        // }
        // 4. 一次性拼接5个，发
        //cli->Send(str);

        // 1. 工厂产生Request
        auto req = factory.BuildRequest();
        // 2. 序列化
        std::string send_str;
        req->Serialize(&send_str);
        std::cout << "Serialize: \n"
                  << send_str << std::endl;
        // 3. 进行添加报头
        send_str = EnCode(send_str);
        std::cout << "Encode: \n"
                  << send_str << std::endl;
        // 4. 进行发送
        cli->Send(send_str);

        // 5. 读取应答
        int n = cli->Recv(&inbuffer);
        if (n < 0)
        {
            break;
        }
        // 6. 截取完整报文
        std::string package = DeCode(inbuffer);
        if (package == std::string())
            continue;
        // 截取出完整有效载荷后， 反序列化会
        auto resp = factory.BuildResponse();
        resp->Deserialize(package);
        // 7. 拿到应答结果
        std::cout << resp->_result << "[" << resp->_code << "]" << std::endl;
    }
    return 0;
}